package battleship;

import org.apache.catalina.Session;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.tagext.IterationTag;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;

public class ShotServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // you made the shot
        System.out.println("ShotServlet post: starting");
    	String userToken= request.getParameter("token");
    	int id= (Integer) UserIdTokenHashMap.idTokenMap.get(userToken);
      //  int id = Integer.parseInt(request.getParameter("id"));
        User user = Context.users[id];
        Game game = user.game;
        User opponent = Context.users[user.opponentID];

        // parse the shot that was made
        String shot = request.getParameter("shot");
        String[] xyStrings = shot.split(",");
        int x = Integer.parseInt(xyStrings[0]);
        int y = Integer.parseInt(xyStrings[1]);
        int[] xy = new int[2];
        xy[0] = x;
        xy[1] = y;
        System.out.println("shot made to " + x + ", " + y);

        PrintWriter out = response.getWriter();
        response.setContentType("text/plain");
        String result = "";
        String coordPairs = "";

        ArrayList<ArrayList<int[]>> oppShips = opponent.ships;
        ArrayList<int[]> oppShipsHit = opponent.hit;
        ArrayList<int[]> oppShipsSunk = opponent.sunk;

        boolean hit = false;
        Iterator<ArrayList<int[]>> oppShipsIterator = oppShips.iterator();
        while (oppShipsIterator.hasNext()) {
//            System.out.println("looking at a ship");
            ArrayList<int[]> ship = oppShipsIterator.next();
            Iterator<int[]> coordsIterator = ship.iterator();
            while (coordsIterator.hasNext()) {
//                System.out.println("looking at a coordinate pair");
                int[] coordinatePair = coordsIterator.next();
//                System.out.println("xy: " + xy + ", comparing against: " + coordinatePair);
                if (Arrays.equals(xy, coordinatePair)) {
                    System.out.println("it's a hit!");
                    hit = true;
                    // it's a hit!

                    // mark the square as being hit
                    int[] hitSquare = {xy[0], xy[1]};
                    oppShipsHit.add(hitSquare);

                    //testing, debugging
//                    System.out.println("CONTENTS OF OPPSHIPSHIT:");
//                    Iterator<int[]> ite = oppShipsHit.iterator();
//                    while (ite.hasNext()) {
//                        int[] temp = ite.next();
//                        System.out.println(temp[0] + ", " + temp[1]);
//                    }
//                    System.out.println("added cell " + xy[0] + "," + xy[1] + " to hit ships");



                    Iterator<int[]> shipIterator = ship.iterator();
                    Iterator<int[]> hitIterator = oppShipsHit.iterator();
                    boolean sunk = true;    // will be set to false if a ship didn't sink
                    while(shipIterator.hasNext()) {
                        int[] next = shipIterator.next();
                        hitIterator = oppShipsHit.iterator();
                        boolean found = false;
                        while(hitIterator.hasNext()) {
                            if (Arrays.equals(next, hitIterator.next())) {
                                found = true;
                                System.out.println("found " + next[0] + "," + next[1] + "!");
                                break;
                            }
                        }
                        if (!found) {
                            // hit, but not sink
                            System.out.println("the cell " + next[0] + "," + next[1] + " still hasn't been hit");
                            System.out.println("it's a hit, but not a sink!");
                            sunk = false;

                            result = "\"result\": \"hit\"";
                            coordPairs = "\"coordPairs\": " + "[" + Arrays.toString(xy) + "]";
                            break;
                        }
                    }
                    if (sunk){
                        // sink
                        System.out.println("it's a sink!");
                        result = "\"result\": \"sink\"";

                        // create ship int[][] to pass back to client as the ship that sunk
                        int[][] sunkShip = new int[ship.size()][2];
                        Iterator<int[]> coordIterator = ship.iterator();
                        for (int i = 0; i < ship.size(); i++) {
                            int[] cs = coordIterator.next();
                            sunkShip[i] = cs;
                            //oppShipsSunk.add(cs); // also add the squares to the list of sunken squares
                        }

                        coordPairs = "\"coordPairs\": " + Arrays.deepToString(sunkShip);
                    }
                }
            }
        }
        // miss
        if (!hit) {
            System.out.println("it's a miss!");
            result = "\"result\": \"miss\"";
            coordPairs = "\"coordPairs\": " + "[" + Arrays.toString(xy) + "]";
        }

        try {
            System.out.println("Starting to put last shot into user's queue. User: " + user.username);
            user.lastShot.put(xy);
            System.out.println("Finished putting last shot into user's queue. User: " + user.username);
        } catch (InterruptedException e) {
            System.out.println("ShotServlet exception: message: " + e.getMessage());
        }

        String reply = "{" + result + ", " + coordPairs + "}";
        System.out.println("ShotServlet: returning: " + reply);
        out.print(reply);
        out.close();
        System.out.println("ShotServlet post: finished");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // you wait for your opponent's shot
        System.out.println("ShotServlet get: starting");

        String userToken= request.getParameter("token");
    	int id= (Integer) UserIdTokenHashMap.idTokenMap.get(userToken);
      //  int id = Integer.parseInt(request.getParameter("id"));
        User user = Context.users[id];
        Game game = user.game;
        User opponent = Context.users[user.opponentID];

        // xy is the shot the opponent made
        int[] xy = new int[2];
        try {
            System.out.println("Starting to take last shot from opponent's queue. Opponent: " + opponent.username);
            xy = opponent.lastShot.take();
            System.out.println("Finshed taking last shot from opponent's queue. Opponent: " + opponent.username);
        } catch (InterruptedException e) {
            System.out.println("ShotServlet get exception: " + e.getMessage());
        }

        String shotString = xy[0] + "," + xy[1];
        System.out.println("shot received at " + shotString);

        PrintWriter out = response.getWriter();
        response.setContentType("text/plain");
        String result = "";
        String coordPairs = "";

        ArrayList<ArrayList<int[]>> yourShips = user.ships;
        ArrayList<int[]> yourShipsHit = user.hit;
        ArrayList<int[]> yourShipsSunk = user.sunk;









        boolean hit = false;
        Iterator<ArrayList<int[]>> yourShipsIterator = yourShips.iterator();
        while (yourShipsIterator.hasNext()) {
//            System.out.println("looking at a ship");
            ArrayList<int[]> ship = yourShipsIterator.next();
            Iterator<int[]> coordsIterator = ship.iterator();
            while (coordsIterator.hasNext()) {
//                System.out.println("looking at a coordinate pair");
                int[] coordinatePair = coordsIterator.next();
//                System.out.println("xy: " + xy + ", comparing against: " + coordinatePair);
                if (Arrays.equals(xy, coordinatePair)) {
                    System.out.println("it's a hit!");
                    hit = true;
                    // it's a hit!

                    // mark the square as being hit
                    int[] hitSquare = {xy[0], xy[1]};
                    yourShipsHit.add(hitSquare);

                    //testing, debugging
//                    System.out.println("CONTENTS OF OPPSHIPSHIT:");
//                    Iterator<int[]> ite = yourShipsHit.iterator();
//                    while (ite.hasNext()) {
//                        int[] temp = ite.next();
//                        System.out.println(temp[0] + ", " + temp[1]);
//                    }
//                    System.out.println("added cell " + xy[0] + "," + xy[1] + " to hit ships");



                    Iterator<int[]> shipIterator = ship.iterator();
                    Iterator<int[]> hitIterator = yourShipsHit.iterator();
                    boolean sunk = true;    // will be set to false if a ship didn't sink
                    while(shipIterator.hasNext()) {
                        int[] next = shipIterator.next();
                        hitIterator = yourShipsHit.iterator();
                        boolean found = false;
                        while(hitIterator.hasNext()) {
                            if (Arrays.equals(next, hitIterator.next())) {
                                found = true;
                                System.out.println("found " + next[0] + "," + next[1] + "!");
                                break;
                            }
                        }
                        if (!found) {
                            // hit, but not sink
                            System.out.println("the cell " + next[0] + "," + next[1] + " still hasn't been hit");
                            System.out.println("it's a hit, but not a sink!");
                            sunk = false;

                            result = "\"result\": \"hit\"";
                            coordPairs = "\"coordPairs\": " + "[" + Arrays.toString(xy) + "]";
                            break;
                        }
                    }
                    if (sunk){
                        // sink
                        System.out.println("it's a sink!");
                        result = "\"result\": \"sink\"";

                        // create ship int[][] to pass back to client as the ship that sank
                        int[][] sunkShip = new int[ship.size()-1][2];
                        Iterator<int[]> coordIterator = ship.iterator();
                        System.out.println("starting with for loop");
                        int j = 0;
                        for (int i = 0; i < ship.size(); i++) {
                            int[] cs = coordIterator.next();
                            System.out.println("Got the next pair of coords");
                            boolean test = Arrays.equals(xy,cs);
                            System.out.println("checked arrays.equals");
                            if (!test) {
                                System.out.println("starting to add coords to sunkShip");
                                sunkShip[j++] = cs;
                                System.out.println("added coords to sunkShip");
                            }
                            System.out.println("starting to add to yourShipsSunk");
                            yourShipsSunk.add(cs); // also add the squares to the list of sunken squares
                            System.out.println("finished adding to yourShipsSunk");
                        }
                        
                        System.out.println("Finished creating ship coords array.");
                        coordPairs = "\"coordPairs\": " + Arrays.deepToString(sunkShip);
                        System.out.println("Finished with deepToString");
                    }
                }
            }
        }
        // miss
        if (!hit) {
            System.out.println("it's a miss!");
            result = "\"result\": \"miss\"";
            coordPairs = "\"coordPairs\": " + "[" + Arrays.toString(xy) + "]";
        }
        
        String target = "\"target\": " + Arrays.toString(xy);
        
        String reply = "{" + result + ", " + coordPairs + ", " + target + "}";
        System.out.println("ShotServlet get: returning: " + reply);
        out.print(reply);
        
        System.out.println("the size of yourShipsSunk is currently: " + yourShipsSunk.size());
        if (yourShipsSunk.size() == 20) { // 20 is the number of squares you have ships on
            try {
                user.gameOver.put(opponent);
                opponent.gameOver.put(opponent);
                System.out.println("put the winner into game over queues");
            } catch (Exception e) {
                System.out.println("ShotServlet get exception 2: " + e.getMessage());
            }

        }
        
        out.close();












//        Iterator<ArrayList<int[]>> iterator1 = yourShips.iterator();
//        while (iterator1.hasNext()) {
//            ArrayList<int[]> ship = iterator1.next();
//            Iterator<int[]> iterator2 = ship.iterator();
//            while (iterator2.hasNext()) {
//                int[] coordinatePair = iterator2.next();
//                if (Arrays.equals(xy, coordinatePair)) {
//                    // it's a hit!
////                    yourShipsHit.add(xy);
//                    Iterator<int[]> shipIterator = ship.iterator();
//                    Iterator<int[]> hitIterator = yourShipsHit.iterator();
//                    while(shipIterator.hasNext()) {
//                        int[] next = shipIterator.next();
//                        boolean found = false;
//                        while(hitIterator.hasNext()) {
//                            if (Arrays.equals(next, hitIterator.next())) {
//                                found = true;
//                            }
//                        }
//                        if (!found) {
//                            System.out.println("the cell " + next[0] + "," + next[1] + " still hasn't been hit");
//                            // hit, but not sink
////                            if (user.equals(game.getPlayer1())) {
////                                try {
////                                    game.shotMadeByPlayer1.put(xy);
////                                } catch (InterruptedException e) {
////                                    System.out.println(e.getMessage());
////                                }
////                            } else {
////                                try {
////                                    game.shotMadeByPlayer2.put(xy);
////                                } catch (InterruptedException e) {
////                                    System.out.println(e.getMessage());
////                                }
////                            }
//
//                            if (yourShipsHit.size() == 20) { // 20 is the number of squares that the ships take up
//                                try {
//                                    game.gameOverQueue.put(user);
//                                } catch (InterruptedException e) {
//                                    System.out.println(e.getMessage());
//                                }
//                            }
//                            out.print(shotString + ";" + "hit");
//                            out.close();
//                            return;
//                        }
//                    }
//                    // sink
////                    if (user.equals(game.getPlayer1())) {
////                        try {
////                            game.shotMadeByPlayer1.put(xy);
////                        } catch (InterruptedException e) {
////                            System.out.println(e.getMessage());
////                        }
////                    } else {
////                        try {
////                            game.shotMadeByPlayer2.put(xy);
////                        } catch (InterruptedException e) {
////                            System.out.println(e.getMessage());
////                        }
////                    }
//                    if (yourShipsHit.size() == 20) { // 20 is the number of squares that the ships take up
//                        try {
//                            game.gameOverQueue.put(user);
//                        } catch (InterruptedException e) {
//                            System.out.println(e.getMessage());
//                        }
//                    }
//                    out.print(shotString + ";" + "sink");
//                    out.close();
//                    return;
//                }
//            }
//        }
//        // miss
////        if (user.equals(game.getPlayer1())) {
////            try {
////                game.shotMadeByPlayer1.put(xy);
////            } catch (InterruptedException e) {
////                System.out.println(e.getMessage());
////            }
////        } else {
////            try {
////                game.shotMadeByPlayer2.put(xy);
////            } catch (InterruptedException e) {
////                System.out.println(e.getMessage());
////            }
////        }
//        if (yourShipsHit.size() == 20) { // 20 is the number of squares that the ships take up
//            try {
//                game.gameOverQueue.put(user);
//            } catch (InterruptedException e) {
//                System.out.println(e.getMessage());
//            }
//        }
//        out.print(shotString + ";" + "miss");
//        out.close();
        System.out.println("ShotServlet get: finished");
    }
}
